using MauiBuilder.Models;
using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Web;

namespace MauiBuilder.Services;

/// <summary>
/// 支付宝支付服务实现
/// </summary>
public class AlipayService : IAlipayService
{
    private PaymentConfig? _config;
    private readonly ILogger<AlipayService> _logger;
    
    /// <summary>
    /// 支付类型
    /// </summary>
    public PaymentType PaymentType => PaymentType.Alipay;
    
    /// <summary>
    /// 是否支持当前平台
    /// </summary>
    public bool IsSupportedPlatform => DeviceInfo.Current.Platform == DevicePlatform.Android || 
                                       DeviceInfo.Current.Platform == DevicePlatform.iOS;

    public AlipayService(ILogger<AlipayService> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 初始化支付配置
    /// </summary>
    public async Task InitializeAsync(PaymentConfig config)
    {
        _config = config ?? throw new ArgumentNullException(nameof(config));
        
        if (string.IsNullOrEmpty(_config.AppId))
            throw new ArgumentException("支付宝AppId不能为空");
        
        if (string.IsNullOrEmpty(_config.PrivateKey))
            throw new ArgumentException("支付宝私钥不能为空");
        
        _logger.LogInformation("支付宝支付服务初始化完成，AppId: {AppId}", _config.AppId);
        await Task.CompletedTask;
    }

    /// <summary>
    /// 创建支付订单
    /// </summary>
    public async Task<PaymentResponse> CreatePaymentAsync(PaymentRequest request)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("支付宝服务未初始化");

            _logger.LogInformation("创建支付宝支付订单，订单号: {OrderId}, 金额: {Amount}", 
                request.OrderId, request.Amount);

            // 构建支付参数
            var bizContent = new
            {
                out_trade_no = request.OrderId,
                total_amount = (request.Amount / 100m).ToString("F2"), // 转换为元
                subject = request.Subject,
                body = request.Body,
                timeout_express = $"{request.TimeoutMinutes}m"
            };

            var parameters = new Dictionary<string, string>
            {
                { "app_id", _config.AppId },
                { "method", "alipay.trade.app.pay" },
                { "charset", _config.Charset },
                { "sign_type", _config.SignType },
                { "timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
                { "version", _config.Version },
                { "biz_content", JsonSerializer.Serialize(bizContent) }
            };

            // 添加回调URL
            if (!string.IsNullOrEmpty(request.NotifyUrl))
                parameters.Add("notify_url", request.NotifyUrl);

            // 生成签名
            var sign = GenerateSign(parameters, _config.PrivateKey, _config.SignType);
            parameters.Add("sign", sign);

            // 构建支付字符串
            var paymentData = BuildPaymentString(parameters);

            return new PaymentResponse
            {
                IsSuccess = true,
                OrderId = request.OrderId,
                Status = PaymentStatus.Pending,
                PaymentData = paymentData,
                CreateTime = DateTime.Now
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建支付宝支付订单失败");
            return new PaymentResponse
            {
                IsSuccess = false,
                OrderId = request.OrderId,
                Status = PaymentStatus.Failed,
                ErrorMessage = ex.Message,
                ErrorCode = "CREATE_ORDER_FAILED"
            };
        }
    }

    /// <summary>
    /// 查询支付结果
    /// </summary>
    public async Task<PaymentResult> QueryPaymentAsync(string orderId)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("支付宝服务未初始化");

            _logger.LogInformation("查询支付宝支付结果，订单号: {OrderId}", orderId);

            var bizContent = new
            {
                out_trade_no = orderId
            };

            var parameters = new Dictionary<string, string>
            {
                { "app_id", _config.AppId },
                { "method", "alipay.trade.query" },
                { "charset", _config.Charset },
                { "sign_type", _config.SignType },
                { "timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
                { "version", _config.Version },
                { "biz_content", JsonSerializer.Serialize(bizContent) }
            };

            var sign = GenerateSign(parameters, _config.PrivateKey, _config.SignType);
            parameters.Add("sign", sign);

            // 这里应该调用支付宝API查询接口
            // 由于是演示代码，这里返回模拟结果
            await Task.Delay(1000); // 模拟网络请求

            return new PaymentResult
            {
                IsSuccess = true,
                OrderId = orderId,
                Status = PaymentStatus.Success,
                Message = "支付成功",
                PayTime = DateTime.Now
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询支付宝支付结果失败");
            return new PaymentResult
            {
                IsSuccess = false,
                OrderId = orderId,
                Status = PaymentStatus.Failed,
                Message = ex.Message
            };
        }
    }

    /// <summary>
    /// 取消支付
    /// </summary>
    public async Task<bool> CancelPaymentAsync(string orderId)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("支付宝服务未初始化");

            _logger.LogInformation("取消支付宝支付，订单号: {OrderId}", orderId);

            // 这里应该调用支付宝取消支付接口
            await Task.Delay(500); // 模拟网络请求

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "取消支付宝支付失败");
            return false;
        }
    }

    /// <summary>
    /// 验证支付回调
    /// </summary>
    public async Task<PaymentResult> VerifyCallbackAsync(Dictionary<string, string> callbackData)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("支付宝服务未初始化");

            _logger.LogInformation("验证支付宝支付回调");

            // 验证签名
            if (!VerifySign(callbackData, _config.PublicKey, _config.SignType))
            {
                return new PaymentResult
                {
                    IsSuccess = false,
                    Status = PaymentStatus.Failed,
                    Message = "签名验证失败"
                };
            }

            var orderId = callbackData.GetValueOrDefault("out_trade_no", "");
            var tradeStatus = callbackData.GetValueOrDefault("trade_status", "");
            var totalAmount = callbackData.GetValueOrDefault("total_amount", "0");

            var status = tradeStatus switch
            {
                "TRADE_SUCCESS" => PaymentStatus.Success,
                "TRADE_FINISHED" => PaymentStatus.Success,
                "TRADE_CLOSED" => PaymentStatus.Cancelled,
                _ => PaymentStatus.Failed
            };

            await Task.CompletedTask;

            return new PaymentResult
            {
                IsSuccess = status == PaymentStatus.Success,
                OrderId = orderId,
                Status = status,
                Amount = decimal.TryParse(totalAmount, out var amount) ? amount * 100 : 0, // 转换为分
                PayTime = DateTime.Now,
                Message = status == PaymentStatus.Success ? "支付成功" : "支付失败",
                RawData = JsonSerializer.Serialize(callbackData)
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证支付宝支付回调失败");
            return new PaymentResult
            {
                IsSuccess = false,
                Status = PaymentStatus.Failed,
                Message = ex.Message
            };
        }
    }

    /// <summary>
    /// 获取支付宝授权信息
    /// </summary>
    public async Task<string> GetAuthInfoAsync()
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("支付宝服务未初始化");

            var parameters = new Dictionary<string, string>
            {
                { "app_id", _config.AppId },
                { "method", "alipay.open.auth.sdk.code.get" },
                { "charset", _config.Charset },
                { "sign_type", _config.SignType },
                { "timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
                { "version", _config.Version }
            };

            var sign = GenerateSign(parameters, _config.PrivateKey, _config.SignType);
            parameters.Add("sign", sign);

            await Task.CompletedTask;
            return BuildPaymentString(parameters);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取支付宝授权信息失败");
            throw;
        }
    }

    /// <summary>
    /// 处理支付宝回调
    /// </summary>
    public async Task<PaymentResult> HandleAlipayResultAsync(string result)
    {
        try
        {
            _logger.LogInformation("处理支付宝支付结果: {Result}", result);

            // 解析支付结果
            var resultData = ParseAlipayResult(result);
            
            var orderId = resultData.GetValueOrDefault("out_trade_no", "");
            var resultStatus = resultData.GetValueOrDefault("resultStatus", "");

            var status = resultStatus switch
            {
                "9000" => PaymentStatus.Success,
                "8000" => PaymentStatus.Processing,
                "4000" => PaymentStatus.Failed,
                "5000" => PaymentStatus.Failed,
                "6001" => PaymentStatus.Cancelled,
                "6002" => PaymentStatus.Failed,
                _ => PaymentStatus.Failed
            };

            await Task.CompletedTask;

            return new PaymentResult
            {
                IsSuccess = status == PaymentStatus.Success,
                OrderId = orderId,
                Status = status,
                PayTime = status == PaymentStatus.Success ? DateTime.Now : null,
                Message = GetStatusMessage(resultStatus),
                RawData = result
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理支付宝支付结果失败");
            return new PaymentResult
            {
                IsSuccess = false,
                Status = PaymentStatus.Failed,
                Message = ex.Message,
                RawData = result
            };
        }
    }

    #region 私有方法

    /// <summary>
    /// 生成签名
    /// </summary>
    private string GenerateSign(Dictionary<string, string> parameters, string privateKey, string signType)
    {
        // 排序参数
        var sortedParams = parameters
            .Where(p => !string.IsNullOrEmpty(p.Value) && p.Key != "sign")
            .OrderBy(p => p.Key)
            .ToList();

        // 构建待签名字符串
        var signString = string.Join("&", sortedParams.Select(p => $"{p.Key}={p.Value}"));

        // 生成签名
        if (signType == "RSA2")
        {
            return SignWithRSA2(signString, privateKey);
        }
        else
        {
            return SignWithRSA(signString, privateKey);
        }
    }

    /// <summary>
    /// RSA2签名
    /// </summary>
    private string SignWithRSA2(string data, string privateKey)
    {
        try
        {
            var keyBytes = Convert.FromBase64String(privateKey);
            using var rsa = RSA.Create();
            rsa.ImportPkcs8PrivateKey(keyBytes, out _);
            
            var dataBytes = Encoding.UTF8.GetBytes(data);
            var signBytes = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            
            return Convert.ToBase64String(signBytes);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "RSA2签名失败");
            throw;
        }
    }

    /// <summary>
    /// RSA签名
    /// </summary>
    private string SignWithRSA(string data, string privateKey)
    {
        try
        {
            var keyBytes = Convert.FromBase64String(privateKey);
            using var rsa = RSA.Create();
            rsa.ImportPkcs8PrivateKey(keyBytes, out _);
            
            var dataBytes = Encoding.UTF8.GetBytes(data);
            var signBytes = rsa.SignData(dataBytes, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
            
            return Convert.ToBase64String(signBytes);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "RSA签名失败");
            throw;
        }
    }

    /// <summary>
    /// 验证签名
    /// </summary>
    private bool VerifySign(Dictionary<string, string> parameters, string publicKey, string signType)
    {
        try
        {
            var sign = parameters.GetValueOrDefault("sign", "");
            if (string.IsNullOrEmpty(sign))
                return false;

            var sortedParams = parameters
                .Where(p => !string.IsNullOrEmpty(p.Value) && p.Key != "sign" && p.Key != "sign_type")
                .OrderBy(p => p.Key)
                .ToList();

            var signString = string.Join("&", sortedParams.Select(p => $"{p.Key}={p.Value}"));

            var keyBytes = Convert.FromBase64String(publicKey);
            using var rsa = RSA.Create();
            rsa.ImportSubjectPublicKeyInfo(keyBytes, out _);

            var dataBytes = Encoding.UTF8.GetBytes(signString);
            var signBytes = Convert.FromBase64String(sign);

            var hashAlgorithm = signType == "RSA2" ? HashAlgorithmName.SHA256 : HashAlgorithmName.SHA1;
            return rsa.VerifyData(dataBytes, signBytes, hashAlgorithm, RSASignaturePadding.Pkcs1);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证签名失败");
            return false;
        }
    }

    /// <summary>
    /// 构建支付字符串
    /// </summary>
    private string BuildPaymentString(Dictionary<string, string> parameters)
    {
        var encodedParams = parameters.Select(p => $"{p.Key}={HttpUtility.UrlEncode(p.Value, Encoding.UTF8)}");
        return string.Join("&", encodedParams);
    }

    /// <summary>
    /// 解析支付宝结果
    /// </summary>
    private Dictionary<string, string> ParseAlipayResult(string result)
    {
        var resultDict = new Dictionary<string, string>();
        
        try
        {
            // 简单的键值对解析
            var pairs = result.Split('&');
            foreach (var pair in pairs)
            {
                var keyValue = pair.Split('=', 2);
                if (keyValue.Length == 2)
                {
                    resultDict[keyValue[0]] = HttpUtility.UrlDecode(keyValue[1]);
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "解析支付宝结果失败");
        }

        return resultDict;
    }

    /// <summary>
    /// 获取状态消息
    /// </summary>
    private string GetStatusMessage(string resultStatus)
    {
        return resultStatus switch
        {
            "9000" => "支付成功",
            "8000" => "支付结果确认中",
            "4000" => "支付失败",
            "5000" => "重复请求",
            "6001" => "用户中途取消",
            "6002" => "网络连接出错",
            _ => "未知状态"
        };
    }

    #endregion
}